package gspringboot

import (
	"errors"
	"gitee.com/hongzhaomin/gspring/iface"
	"sync/atomic"
)

type AppContextType string

var appCtxTypes atomic.Pointer[map[AppContextType]ApplicationContextFactory]

func AddCustomizeAppContextFactory(appCtxType AppContextType, appCtxFactory ApplicationContextFactory) {
	load := *appCtxTypes.Load()
	if _, ok := load[appCtxType]; ok {
		panic(errors.New("application contexts factory is exist: " + string(appCtxType)))
	}
	load[appCtxType] = appCtxFactory
	appCtxTypes.Store(&load)
}

func appCtxTypeMap() map[AppContextType]ApplicationContextFactory {
	return *appCtxTypes.Load()
}

const (
	WebApp    AppContextType = "web"
	CommonApp AppContextType = "common"
)

func (my AppContextType) is(appCtxType AppContextType) bool {
	return appCtxType == WebApp
}

func (my AppContextType) isValid() bool {
	_, ok := appCtxTypeMap()[my]
	return ok
}

func (my AppContextType) getAppCtxFactory() ApplicationContextFactory {
	return appCtxTypeMap()[my]
}

// ApplicationContextFactory 定义app上下文工厂
type ApplicationContextFactory interface {
	Create(appType AppContextType, env iface.Environment) ConfigurationApplicationContext
}

// DefaultApplicationContextFactory 默认app上下文工厂：webApp
type DefaultApplicationContextFactory struct{}

func (my DefaultApplicationContextFactory) Create(appType AppContextType, env iface.Environment) ConfigurationApplicationContext {
	envAppType := AppContextType(env.GetString(appContextTypePropName))
	if !envAppType.isValid() {
		envAppType = appType
	}
	if WebApp.is(envAppType) {
		return NewWebApplicationContext()
	}
	return envAppType.getAppCtxFactory().Create(envAppType, env)
}

// CommonApplicationContextFactory 普通app上下文工厂：无web功能
type CommonApplicationContextFactory struct{}

func (my CommonApplicationContextFactory) Create(_ AppContextType, _ iface.Environment) ConfigurationApplicationContext {
	return NewCommonApplicationContext()
}
